import inquirer from 'inquirer';
import * as path from 'path';
import config from '../config';
import { eachFiles, executeCmd, getCliConfigData, isDirectoryEmpty, trimPath } from '../utils';

/**
 * 生成空格字符串
 */
function createSpaceStr(len: number) {
    if (len <= 0) return '';
    return new Array(len).fill(' ').join('');
}

function numberToString(num: number) {
    if (num < 10) return `0${num}`;
    return `${num}`;
}

export default async function main(projectPath: string) {
    projectPath = trimPath(projectPath);
    console.log('项目路径: ' + projectPath);
    if (!projectPath || isDirectoryEmpty(projectPath)) return console.log('请输入有效文件夹路径');

    // 获取cliconfig数据
    const projectCliData = getCliConfigData(projectPath);
    if (!projectCliData) return console.log('未在项目根目录下找到cliconfig.json');

    // 获取引擎类型
    if (!config.types[projectCliData.type]) {
        return console.log(`未知的引擎类型: ${projectCliData.type}`);
    }

    if (projectCliData.type !== config.types.Creator3D) {
        return console.log(`不支持的引擎类型: ${projectCliData.type}`);
    }

    const operate = await inquirer.prompt([
        {
            name: 'type',
            type: 'list',
            message: '选择操作行为',
            default: '安装',
            choices: ['安装', '卸载', '更新', '退出']
        }
    ]);

    if (operate.type === '更新') {
        const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
        console.log('更新中: npm run --prefix ./extensions/pkg update');
        await executeCmd(npm, ['run', '--prefix', './extensions/pkg', 'update']);
        main(projectPath);
    } else if (operate.type === '安装') {
        // 筛选所有类型
        const types = Array.from(new Set(config.pkgs.map(info => info.type)));
        // 选择类型
        const type = await inquirer.prompt([
            {
                name: 'name',
                type: 'list',
                message: '选择类型',
                default: types[0],
                choices: types
            }
        ]);
        // 根据所选类型筛选扩展包
        const pkgs = config.pkgs.filter(info => info.type === type.name);
        // 根据扩展包列表生产选择列表
        let maxNameLen = 0;
        pkgs.forEach((info) => { if (info.name.length > maxNameLen) maxNameLen = info.name.length; });
        const packages = pkgs.map((info, i) => `${numberToString(i + 1)}) ${info.type} | ${info.name}${createSpaceStr(maxNameLen - info.name.length)} | ${info.desc}`);
        const install = await inquirer.prompt([
            {
                name: 'package',
                type: 'list',
                message: '选择' + type.name,
                default: packages[0],
                choices: packages
            },
            {
                name: 'sure',
                type: 'confirm',
                message: '是否确认?'
            }
        ]);

        if (!install.sure) return;

        const index = packages.indexOf(install.package);
        if (index === -1) return;

        const packageName = pkgs[index].name;

        const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
        console.log('安装中: npm run --prefix ./extensions/pkg add ' + packageName);
        await executeCmd(npm, ['run', '--prefix', './extensions/pkg', 'add', packageName]);
        main(projectPath);
    } else if (operate.type === '卸载') {
        const node_modules = path.join(projectPath, 'extensions/pkg/node_modules');

        const packageNames: string[] = [];
        eachFiles(node_modules, (item_path, isDirectory) => {
            if (!isDirectory) return;
            const basename = path.basename(item_path);
            if (!basename.startsWith('@')) {
                packageNames.push(basename);
            } else {
                eachFiles(item_path, (sub_path, isDirectory) => {
                    if (!isDirectory) return;
                    const subname = path.basename(sub_path);
                    packageNames.push(basename + '/' + subname);
                });
            }
        });

        if (packageNames.length === 0) {
            return console.log('未安装任何package');
        }

        const uninstall = await inquirer.prompt([
            {
                name: 'package',
                type: 'list',
                message: '选择package',
                default: packageNames[0],
                choices: packageNames
            },
            {
                name: 'sure',
                type: 'confirm',
                message: '是否确认?'
            }
        ]);

        if (!uninstall.sure) return;

        const packageName = uninstall.package;
        const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
        console.log('卸载中: npm run --prefix ./extensions/pkg remove ' + packageName);
        await executeCmd(npm, ['run', '--prefix', './extensions/pkg', 'remove', packageName]);
        main(projectPath);
    }
}